
import audioLoader from 'audio-loader';
import { exec } from 'child_process';
import fs1 from 'fs';
import fs from 'fs/promises';
import os from 'os';
import pLimit from 'p-limit';
import path from 'path';


const configPath = './config.json';

const loadConfig = (configPath) => {
  try {
    const rawData = fs1.readFileSync(configPath);
    return JSON.parse(Buffer.from(rawData).toString().replace(/\\/g, '\\\\'));
  } catch (err) {
    console.error('配置文件读取失败:', err);
    return null;
  }
};

const configJson = loadConfig(configPath);


const start = process.hrtime();

// 限制并发数为CPU核心数×2
const concurrencyLimit = pLimit(os.cpus().length * 2);
const AUDIO_EXTENSIONS = new Set(['.mp3', '.wav', '.ogg', '.flac', '.aac', '.m4a']);

async function scanAudioFiles(dirPath, recursive = true) {
  const results = [];
  const queue = [{ path: dirPath, depth: 0 }];

  while (queue.length) {
    const { path: currentPath, depth } = queue.shift();
    try {
      const items = await fs.readdir(currentPath);

      await Promise.all(items.map(async item => {
        const fullPath = path.join(currentPath, item);
        const stat = await fs.stat(fullPath);

        if (stat.isDirectory() && recursive && depth < 10) {
          queue.push({ path: fullPath, depth: depth + 1 });
        } else if (stat.isFile() && AUDIO_EXTENSIONS.has(path.extname(item).toLowerCase())) {
          results.push({
            path: fullPath,
            size: stat.size,
            modified: stat.mtime
          });
        }
      }));
    } catch (err) {
      console.error(`扫描失败: ${currentPath}`, err);
    }
  }
  return results;
}

async function processAudioFiles(files) {
  return Promise.all(files.map(file =>
    concurrencyLimit(() => audioLoader(file.path)
      .then(({ duration }) => {
        const reserveTime = configJson.reserveTime;
        const timeLits = reserveTime.split('-').map(Number);

        if (duration < timeLits[0] || duration >= timeLits[1]) {
          console.log(`删除: ${file.path} (${duration}s)`);
          return new Promise((resolve, reject) => {
            exec(`del "${file.path}"`, (err) =>
              err ? reject(err) : resolve());
          });
        }
      })
      .catch(err => {
        console.error(`处理失败: ${file.path}`, err);
      })
    )
  ));
}

(async () => {
  const audioFiles = await scanAudioFiles(configJson.audioFolder);
  await processAudioFiles(audioFiles);
  console.log(`处理完成，共处理${audioFiles.length}个文件`);

  const diff = process.hrtime(start);
  console.log(`执行耗时: ${diff[0]}秒 ${diff[1] / 1000000}毫秒`);
})();
